home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 181_01 / carne_fp.cod < prev    next >
Text File  |  1986-01-07  |  22KB  |  716 lines

  1. Reprinted from: Micro/Systems Journal, Volume 1. No. 5. Nov/Dec 1985    
  2. Article Title: "Faster Floating Point Math"
  3. Author: Ted Carnevale
  4. -----------------------------------------------------------------
  5. Copy of back issue may be obtained for $4.50 (foreign $6) from:
  6. Micro/Systems Journal
  7. Box 1192
  8. Mountainside NJ 07092
  9. -----------------------------------------------------------------
  10. Copyright 1986
  11. Micro/Systems Journal, Box 1192, Mountainside NJ 07092
  12. This software is released into the public domain for
  13.  non-commercial use only.
  14. -----------------------------------------------------------------
  15.  
  16.  
  17.                                   Listing 1
  18.  
  19.                                   =========
  20.  
  21. /* fpc.c--tests conversion to/from amd9511 fpp format */
  22.  
  23. #include fprintf.h
  24. #include c80def.h
  25.  
  26. #define MESSAGE  "\nFloating-point format conversion program")
  27. #define DASHES "\n\n----------------------------------------")
  28.  
  29. #define MAX 6   /* how many different values to feed 
  30.                      to the format conversion routines */
  31.  
  32. /* replace the next two functions with 
  33.      your own format conversion routines as needed */
  34. extern long c2amd();    /* link .rel file containing these */
  35. extern float amd2c();   /*   to fpc.rel */
  36.  
  37. main()
  38. {
  39.         int i;
  40.         static int sx=10;
  41.         float x;
  42.         static float dx=1.0;
  43.  
  44.         printf(MESSAGE);
  45.         printf(DASHES);
  46.  
  47.         /* a geometric series of positive values */
  48.         for (i = 0, x = 100.0; i<=MAX; x /= sx, i++) showbits(x);
  49.         printf(DASHES);
  50.  
  51.         /* a geometric series of negative values */
  52.         for (i = 0, x = -100.0; i<=MAX; x /= sx, i++) showbits(x);
  53.         printf(DASHES);
  54.  
  55.         /* a linear series of positive and negative values */
  56.         for (i = -MAX, x=(float)(-MAX); i<=MAX; x += dx, i++) showbits(x);
  57. }
  58.  
  59.  
  60. /* show bit patterns used by C80 and AMD FPP floating point formats 
  61.      to represent the float n */
  62. showbits(n)
  63. float n;
  64. {
  65.         int i;
  66.         union {
  67.                 float f;
  68.                 long l;
  69.         } x,z;  /* unions are easier to use here than pointers */
  70.         long y;
  71.  
  72.         x.f=n;
  73.  
  74.         /* show C80's preconversion bit pattern */
  75.         printf("\n\nx = %e,\t\tBCDE = ",x.f);
  76.         prntlong(x.l);
  77.  
  78. /* eliminate next few lines if you just want to check the format
  79.      used by your version of C */
  80.         /* show AMD formatted data */
  81.         y=c2amd(x.f);
  82.         printf("\n\t\t\t\t AMD = ");
  83.         prntlong(y);
  84.  
  85.         /* convert back to C80's format */
  86.         z.f=amd2c(y);
  87.         printf("\nz = %e,\t\tBCDE = ",z.f);
  88.         prntlong(z.l);
  89. /* end of C80 -> AMD -> C80 format conversion test */
  90. }
  91.  
  92.  
  93. /* print bit pattern of a long, starting with the high-order bit
  94.      of the most significant byte, working down from left to right */
  95. prntlong(k)
  96. long k;
  97. {
  98.         int i;
  99.         union {
  100.                 long l;
  101.                 char b[4];
  102.         } datum;
  103.  
  104.         datum.l=k;
  105.         for (i=3; i>=0; i--) {
  106.                 prntbyt(datum.b[i]);
  107.                 printf(" ");
  108.         }
  109. }
  110.  
  111.  
  112. /* print the bit pattern for a byte from left to right, 
  113.      high order bit first (does the dirty work for prntlong) */
  114. prntbyte(i)
  115. int i;
  116. {
  117.         int j;
  118.         char bit;
  119.  
  120.         for (j=0x80; j>0; j=j>>1) {
  121.                 if (i & j) bit='1';
  122.                 else bit='0';
  123.                 printf("%c",bit);
  124.         }
  125. }
  126.                                   Listing 2
  127.                                   =========
  128.  
  129.         TITLE FLTLB
  130.         PAGE 64
  131. ; Floating point library
  132. ; C/80 3.0 (7/7/83) - (c) 1983 Walter Bilofsky
  133. ;MODIFIED 8/84 to use amd9511 for floating point multiply/divide 
  134. ;and MATHLIB functions as well.  
  135. ;Replaces modules FLTLIB and MATHLIB
  136. ; -- N.T.Carnevale
  137. ;
  138. ;
  139. ;these were gleaned from LIB's listing of FLIBRARY.REL:
  140. ;
  141. ENTRY Bf.Bl,Bf.Hc,Bf.Hi,Bf.Hu,Bl.Bf
  142. ENTRY cf.eq,cf.ge,cf.gt,cf.le,cf.lt,cf.ne
  143. ENTRY div10.,mul10.
  144. ENTRY dum_
  145. ENTRY errcod
  146. ENTRY F.add,F.div,F.mul,F.neg,F.not,F.sub
  147. ENTRY facl_,facl_1,facl_2,fac_,fac_1
  148. ENTRY fadd.,fadda.,fcomp.,fdiv_a,fdiv_b,fdiv_c,fdiv_g
  149. ENTRY flneg.,float.,flt.0,flt_pk
  150. ENTRY fmlt_1,fmlt_2
  151. ENTRY Hc.Bf,Hi.Bf,Hu.Bf
  152. ENTRY inxhr.
  153. ENTRY movfm.,movfr.,movmf.,movrf.
  154. ENTRY pushf.,qint.,save_,save_1,sign.,zero.
  155. ;
  156. EXTRN c.neg,c.sxt,eq.4,g.,Hc.Bl,Hi.Bl,Hu.Bl,L.add,L.neg
  157. EXTRN llong.,movrm.,neq.4,slong.
  158. ;
  159. ;this preserves the 15 byte data area revealed by LIB:
  160.         DSEG
  161. ;
  162. facl_:  DB      0
  163. facl_1: DB      0
  164. facl_2: DB      0
  165. fac_:   DB      0
  166. fac_1:  DB      0
  167. save_:  DB      0
  168. fmlt_1: DB      0
  169. fmlt_2: DB      0
  170. dum_:   DB      0
  171. save_1: DB      0
  172. errcod: DB      0
  173. fdiv_a: DB      0
  174. fdiv_b: DB      0
  175. fdiv_c: DB      0
  176. fdiv_g: DB      0
  177. ;
  178. ;       CSEG
  179. ;
  180. flt_pk: DS      0
  181. F.add:  XRA     A
  182.         JMP     Dual
  183. F.sub:  MVI     A,1
  184.         JMP     Dual
  185. F.mul:  JMP     fpmul           ;jump to new routines
  186. ;       MVI     A,2
  187. ;       JMP     Dual
  188. F.div:  JMP     fpdiv
  189. ;       MVI     A,3
  190. Dual:   CALL    movfr.
  191.      
  192.  
  193.                                   Listing 3
  194.                                   =========
  195.  
  196. Ftab:   DW      fadd.
  197.         DW      fsub            ;next two addresses not used
  198. ;       DW      fpmul
  199. ;       DW      fpdiv
  200.                                   Listing 4
  201.                                   =========
  202.  
  203. ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  204. ;
  205. ;
  206. ;What follows replaces the original code in the FLTLIB section of
  207. ;FLOATLIB.ASM that started with fmult3: and ended just before pophrt:.
  208.         ;
  209.         ;
  210. CR      EQU 0DH
  211. LF      EQU 0AH
  212. BDOS    EQU 5
  213. BOOT    EQU 0
  214. PSTRNG  EQU 9
  215.         ;
  216.         ;
  217.         ;send message to console
  218. PRMSG:
  219.         PUSH PSW
  220.         PUSH B
  221.         PUSH D
  222.         PUSH H
  223.         MVI C,PSTRNG
  224.         CALL BDOS
  225.         POP H
  226.         POP D
  227.         POP B
  228.         POP PSW
  229.         RET
  230.         ;
  231. ;**************************************************************
  232.         ;
  233.         ;
  234.         ;Port addresses
  235.         ;
  236. BASE    EQU 050H        ;base address of Compupro SS1 board
  237. CREG    EQU BASE+9      ;location of 9511's control & data ports
  238. DREG    EQU BASE+8
  239.         ;
  240.         ;
  241.         ;FPP error codes
  242.         ;
  243. ERRBITS EQU 1EH         ;the status register's error bits
  244. OVRFLO  EQU 2           ;overflow
  245. UNRFLO  EQU 4           ;underflow
  246. NEGARG  EQU 8           ;negative argument to sqrt or log function
  247. DIVZER  EQU 10H         ;divide by zero
  248. TOOBIG  EQU 18H         ;arg of asin, acos, or exp too big
  249.         ;
  250.         ;
  251.         ;FPP command codes
  252.         ;
  253. FMUL    EQU 12H
  254. FDIV    EQU 13H
  255. XCHF    EQU 19H         ;swap top two locations in fpp's stack
  256. FSQRT   EQU 1
  257. FSIN    EQU 2
  258. FCOS    EQU 3
  259. FTAN    EQU 4
  260. FASIN   EQU 5
  261. FACOS   EQU 6
  262. FATAN   EQU 7
  263. FLOG    EQU 8           ;log base 10
  264. FLN     EQU 9           ;natural logarithm
  265. FEXP    EQU 0AH         ;e^x
  266. FPWR    EQU 0BH         ;x^y
  267.         ;
  268. ;**************************************************************
  269. ;**************************************************************
  270. ;
  271. ;
  272. ;note:  timing indicated for some of the following
  273. ;
  274. ;This block converts c80 float in BD to FPP format, then loads it into FPP.  
  275. ;If out of range for FPP, aborts with warning.
  276. ;
  277. ;Data format conversion routine C2AMD--
  278. ;converts c80's float to amd's fp format.
  279. ;Based on suggestions by J.Shook, Electronics Lab, Dept.of Chemistry,
  280. ;SUNY Stony Brook
  281. ;
  282. ;Floating point formats
  283. ;----------------------
  284. ;C80 stores floats as:
  285. ;        mantissa sign in C7
  286. ;        mantissa  =  24 bit two's complement in CDE, 
  287. ;                        with bit 23 assumed = 1.
  288. ;        exponent is added to 128 (80H) and stored in B.  
  289. ;                        If the number is 0, B=0.
  290. ;
  291. ;FPP stores floats as:
  292. ;        mantissa sign in B7
  293. ;        mantissa  =  24 bit two's complement in CDE,
  294. ;                        with bit 23 = 1.  However, 
  295. ;                        the value 0 is represented by BD=0.
  296. ;        exponent sign in B6
  297. ;        exponent in B5-B0 (only 6 bits).
  298. ;
  299. ;
  300.         ;Call with value to convert